﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LeafTransmission.Utils
{
    /// <summary>
    /// 文件工具类
    /// </summary>
    internal class FileUtil
    {
        public static readonly string KEY_EXISTS = "exists";
        public static readonly string KEY_PATH = "path";
        public static readonly string KEY_SUCCESS = "success";
        public static readonly string VALUE_TRUE = "True";
        public static readonly string VALUE_FALSE = "False";

        #region 文件/目录的创建操作
        /// <summary>
        /// 在指定目录下创建文件
        /// 若不存在指定文件 则创建
        /// 若存在 则不创建
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <param name="absolutePath">绝对路径</param>
        /// <param name="subDirectory">绝对路径下的子目录,可选参数</param>
        /// <returns>
        ///     IDictionary<string, string>
        ///     key             value
        ///     success         创建成功返回string类型True, 创建失败返回string类型False
        ///                     注意: 当目录存在时,也是返回string类型的False
        ///     path            无论成功与否,都返回 工作目录+子目录+文件名 拼接而成的字符串
        /// </returns>
        public static IDictionary<string, string> CreateFileIfNotExists(string filename, string absolutePath, params string[] subDirectory)
        {
            IDictionary<string, string> result = new Dictionary<string, string>();

            string path = ContactFilePath(filename, absolutePath, subDirectory);

            if (JudgeFileExists(filename, absolutePath, subDirectory))// 存在,则不创建
            {
                result.Add(KEY_SUCCESS, VALUE_FALSE);
                result.Add(KEY_PATH, path);
                return result;
            }
            else
            {
                /*
                 * 程序到这里,表示文件或路径不存在
                 * 若不存在则创建一下目录
                 */
                CreateDirectoryIfNotExists(absolutePath, subDirectory);

                File.Create(path).Close();
                result.Add(KEY_SUCCESS, VALUE_TRUE);
                result.Add(KEY_PATH, path);
                return result;
            }

        }

        /// <summary>
        /// 是否不管文件存在与否,都创建该文件
        /// 也就是文件的覆盖
        /// </summary>
        /// <param name="force">true 强制创建, false 存在则不创建</param>
        /// <param name="filename">文件名</param>
        /// <param name="absolutePath">绝对路径</param>
        /// <param name="subDirectory">绝对路径下的子目录</param>
        /// <returns>
        ///     IDictionary<string, string>
        ///     key             value
        ///     success         创建成功返回string类型True, 创建失败返回string类型False
        ///                     注意: 当目录存在时,也是返回string类型的False
        ///     path            无论成功与否,都返回 工作目录+子目录+文件名 拼接而成的字符串
        /// </returns>
        public static IDictionary<string, string> CreateFileForce(bool force, string filename, string absolutePath, params string[] subDirectory)
        {
            IDictionary<string, string> result = new Dictionary<string, string>();

            string path = ContactFilePath(filename, absolutePath, subDirectory);
            if (force)
            {
                CreateDirectoryIfNotExists(absolutePath, subDirectory);

                File.Create(path).Close();
                result.Add(KEY_SUCCESS, VALUE_TRUE);
                result.Add(KEY_PATH, path);
                return result;
            }
            else
            {
                return CreateFileIfNotExists(filename, absolutePath, subDirectory);
            }

        }

        /// <summary>
        /// 在指定目录下创建目录
        /// 若不存在指定目录 则创建
        /// </summary>
        /// <param name="absolutePath">指定绝对目录</param>
        /// <param name="subDirectory">绝对路径下的子目录,可选参数</param>
        /// <returns>
        ///     IDictionary<string, string>
        ///     key             value
        ///     success         创建成功返回string类型True, 创建失败返回string类型False
        ///                     注意: 当目录存在时,也是返回string类型的False
        ///     path            无论成功与否,都返回 指定目录+子目录 拼接而成的字符串
        /// </returns>
        public static IDictionary<string, string> CreateDirectoryIfNotExists(string absolutePath, params string[] subDirectory)
        {
            IDictionary<string, string> result = new Dictionary<string, string>();

            string path = ContactDirectoryPath(absolutePath, subDirectory);

            if (JudgeDirectoryExists(absolutePath, subDirectory))// 表示存在,则不用创建
            {
                result.Add(KEY_SUCCESS, VALUE_FALSE);
                result.Add(KEY_PATH, path);
                return result;
            }
            else
            {
                Directory.CreateDirectory(path);

                result.Add(KEY_SUCCESS, VALUE_TRUE);
                result.Add(KEY_PATH, path);
                return result;
            }
        }


        /// <summary>
        /// 在当前工作目录下创建文件
        /// 若不存在指定文件 则创建
        /// 若存在 则不创建
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <param name="subDirectory">当前工作目录下的子目录,可选参数</param>
        /// <returns>
        ///     IDictionary<string, string>
        ///     key             value
        ///     success         创建成功返回string类型True, 创建失败返回string类型False
        ///                     注意: 当目录存在时,也是返回string类型的False
        ///     path            无论成功与否,都返回 工作目录+子目录+文件名 拼接而成的字符串
        /// </returns>
        public static IDictionary<string, string> CreateFileInPWDIfNotExists(string filename, params string[] subDirectory)
        {
            return CreateFileIfNotExists(filename, Directory.GetCurrentDirectory(), subDirectory);
        }

        /// <summary>
        /// 在当前工作目录下创建目录
        /// 若不存在指定目录 则创建
        /// 若存在 则不创建
        /// </summary>
        /// <param name="subDirectory">当前工作目录下的子目录,可选参数</param>
        /// <returns>
        ///     IDictionary<string, string>
        ///     key             value
        ///     success         创建成功返回string类型True, 创建失败返回string类型False
        ///                     注意: 当目录存在时,也是返回string类型的False
        ///     path            无论成功与否,都返回 工作目录+子目录 拼接而成的字符串
        /// </returns>
        public static IDictionary<string, string> CreateDirectoryInPWDIfNotExists(params string[] subDirectory)
        {
            return CreateDirectoryIfNotExists(Directory.GetCurrentDirectory(), subDirectory);
        }
        #endregion

        #region 文件/目录 是否存在判断
        /// <summary>
        /// 判断指定目录在工作目录下是否存在
        /// relativePath格式 Config, tmp, 若有多层目录按顺序传递参数
        /// </summary>
        /// <param name="subDirectory">当前工作目录下的子目录, 可选参数</param>
        /// <returns>
        ///     IDictionary<string, string>
        ///     Key         Value
        ///     exists      若存在则返回string类型的 True, 若不存在则返回string类型的 False
        ///     path        工作目录+子目录 的路径拼接字符串,方便后续的使用
        /// </returns>
        public static IDictionary<string, string> JudgeDirectoryExistsInCurrentDirectory(params string[] subDirectory)
        {
            IDictionary<string, string> dictionary = new Dictionary<string, string>();

            string path = ContactDirectoryPath(Directory.GetCurrentDirectory(), subDirectory);
            dictionary.Add(KEY_EXISTS, JudgeDirectoryExists(path).ToString());
            dictionary.Add(KEY_PATH, path);
            return dictionary;
        }


        /// <summary>
        /// 判断文件在工作目录是否存在
        /// filename格式 NetworkConfig.xml
        /// relativePath格式 Config 若有多层目录请按顺序依次添加参数
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <param name="subDirectory">子目录</param>
        /// <returns>
        ///     IDictionary<string, string>
        ///     Key         Value
        ///     exists      若存在则返回string类型的 True, 若不存在则返回string类型的 False
        ///     path        工作目录+子目录+文件名称 的路径拼接字符串,方便后续的使用
        /// </returns>
        public static IDictionary<string, string> JudgeFileExistsInCurrentDirectory(string filename, params string[] subDirectory)
        {
            IDictionary<string, string> dictionary = new Dictionary<string, string>();

            string absolutePath = ContactDirectoryPath(Directory.GetCurrentDirectory(), subDirectory);
            string path = ContactFilePath(filename, absolutePath);

            dictionary.Add(KEY_EXISTS, JudgeFileExists(filename, absolutePath).ToString());
            dictionary.Add(KEY_PATH, path);
            return dictionary;

        }

        /// <summary>
        /// 判断目录是否存在
        /// </summary>
        /// <param name="absolutePath">绝对路径</param>
        /// <param name="subDirectory">绝对路径下的子目录,可选参数</param>
        /// <returns>return true if file exists</returns>
        public static bool JudgeDirectoryExists(string absolutePath, params string[] subDirectory)
        {
            string path = ContactDirectoryPath(absolutePath, subDirectory);
            return Directory.Exists(path);
        }

        /// <summary>
        /// 判断文件在指定路径下是否存在
        /// path格式  D:\VS_workspace\Console2\Console2\bin\Debug\net6.0
        /// filename格式 NetworkConfig.xml
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <param name="absolutePath">绝对路径</param>
        /// <param name="subDirectory">绝对路径的子目录,可选参数</param>
        /// <returns>return true if file exists</returns>
        public static bool JudgeFileExists(string filename, string absolutePath, params string[] subDirectory)
        {
            string path = ContactFilePath(filename, absolutePath, subDirectory);
            return File.Exists(path);
        }
        #endregion

        #region 文件/目录的路径拼接操作
        /// <summary>
        /// 拼接目录与文件名
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <param name="absolutePath">绝对路径</param>
        /// <param name="subDirectory">句对路径下的子目录,可选参数</param>
        /// <returns>绝对路径 + 子目录 + 文件名</returns>
        public static string ContactFilePath(string filename, string absolutePath, params string[] subDirectory)
        {
            string path = ContactDirectoryPath(absolutePath, subDirectory);
            return Path.Combine(@path, filename);
        }

        /// <summary>
        /// 拼接目录路径
        /// </summary>
        /// <param name="absolutePath">绝对路径</param>
        /// <param name="subDirectory">绝对路径下的子目录</param>
        /// <returns>绝对路径 + 子目录</returns>
        public static string ContactDirectoryPath(string absolutePath, params string[] subDirectory)
        {
            string[] paths;
            if (subDirectory.Length > 0)
            {
                paths = new string[subDirectory.Length + 1];
                paths[0] = @absolutePath;
                for (int i = 0; i < subDirectory.Length; i++)
                {
                    paths[i + 1] = subDirectory[i];
                }

                return Path.Combine(paths);
            }
            else
            {
                return absolutePath;
            }

        }
        #endregion
    }
}
